public class IdeaUserStory 
{
	//recursion control methods - for use in the IdeaWorkflowStepToUserStoryStatus method. This method updates the triggering object
	//so we have to close the loop.
	private static boolean alreadyUpdatedIdea = false;
    public static boolean hasAlreadyUpdatedIdea() 
    {
    return alreadyUpdatedIdea;
    }
    public static void setAlreadyUpdatedIdea() 
    {
    alreadyUpdatedIdea = true;
    }
    //end recursion control methods
	
	//This method takes the idea workflow step and uses it to update the associated user story's status if an ontime link
	//does not yet exist. called by an idea after update trigger.
	//We're doing this with apex rather than a formula to enable the trigger of automated emails at the case level.
	public static void IdeaWorkflowStepToUserStoryStatus(idea[] ideas)
	{
			Map<id,string> userStoryIdWorkflowStepMap = new Map<id,string>();
			Map<id,string> userStoryIdIdeaURLMap = new Map<id,string>();
			for (integer i = 0; i < ideas.size(); i++)	
			{		
				if(ideas[i].user_story__c != Null)
				{
					userStoryIdWorkflowStepMap.put(ideas[i].user_story__c,ideas[i].workflow_step__c);
					userStoryIdIdeaURLMap.put(ideas[i].user_story__c,'https://na6.salesforce.com/ideas/viewIdea.apexp?id=' + ideas[i].Id);
				}	
			}	
			if (userStoryIdWorkflowStepMap.isempty()==false)
			{
				list<user_story__c> updateUserStories = new list<user_story__c>();
				for (user_story__c u: [select id,status__c,OnTime_Id__c from user_story__c where id in :userStoryIdWorkflowStepMap.keyset()])	
				{	
					If (u.OnTime_Id__c==null)
					{
						u.status__c = userStoryIdWorkflowStepMap.get(u.id);
						u.idea_URL__c = userStoryIdIdeaURLMap.get(u.id);
						if (userStoryIdWorkflowStepMap.get(u.id)=='Selected For Consideration')
						{
							u.send_to_ontime__C = true;
						}
						updateUserStories.add(u);
					}
				}
				update updateUserStories;
			}
	}
	
	//This method ensures the user story status and idea status are in synch whenever the idea is updated
	public static void SynchIdeaUserStoryStatusFromIdea(idea[] ideas)
	{
		List<id>ideaIdList = new List<id>();
		for (integer i = 0; i < ideas.size(); i++)	
		{		
			if(ideas[i].user_story__c != Null)
			{
				ideaIdList.add(ideas[i].id);
			}	
		}
		if (ideaIdList.size()>0)
		{
			list<idea> updateIdeas = New List<idea>();
			for(idea i:[select status,user_story_status_formula__c from idea where id in :ideaIdList])
			{
				if (i.user_story_status_Formula__c.contains('Addressed in Release'))
				{
					if(i.status!='Addressed in Release')
					{
						i.status='Addressed in Release';
						updateIdeas.add(i);
					}
				}
				else
				{
					if(i.status!=i.User_Story_Status_Formula__c)if(i.User_Story_Status_Formula__c!=null)
					{
						i.status=i.User_Story_Status_Formula__c;
						updateIdeas.add(i);
					}
				}
			}
			Update updateIdeas;		
		}
	}
	
	//This method ensures the user story status and idea status are in synch whenever the user Story is updated
	public static void SynchIdeaUserStoryStatusFromUserStory(user_story__c[] userStories)
	{
		List<id>userStoryIdList = new List<id>();
		for (integer i = 0; i < userStories.size(); i++)	
		{		
			if(userStories[i].Ontime_Id__c != Null)
			{
				userStoryIdList.add(userStories[i].id);
			}	
		}
		
		if (userStoryIdList.size()>0)
		{
			list<idea> updateIdeas = New List<idea>();
			for(idea i:[select status,user_story_status_formula__c from idea where user_story__c in :userStoryIdList])
			{
				if (i.user_story_status_Formula__c.contains('Addressed in Release'))
				{
					if(i.status!='Addressed in Release')
					{
						i.status='Addressed in Release';
						updateIdeas.add(i);
					}
				}
				else
				{
					if(i.status!=i.User_Story_Status_Formula__c)
					{
						i.status=i.User_Story_Status_Formula__c;
						updateIdeas.add(i);
					}
				}
			}
			Update updateIdeas;		
		}
	}
	
	//This method looks for a value in the "Available in Release" field. If it finds one, the status of the user story is changed to
	//"available in release xxxx"	
	public static void StatusAvailableInRelease(User_Story__c[] UserStories)
	{
		for (Integer x = 0; x < UserStories.size(); x++) 
		{
			List <id> UserStoryIdList = New List<id>();
			List <User_Story__c> updateUserStories = New List<User_Story__c>();
			If (UserStories[x].available_in_release__c != null)
			{
				UserStoryIdList.add(UserStories[x].id);
			}
			If (UserStoryIdList.size()>0)
			{
				for (User_Story__c u:[select status__c,available_in_release__r.name from User_Story__c where id in :UserStoryIdList]) 
				{
					If(u.status__c != 'Addressed in Release ' + u.available_in_release__r.name) 
					{
						u.status__c = 'Addressed in Release ' + u.available_in_release__r.name;
						updateUserStories.add(u);
					}
				}
				update updateUserStories;
			}
		}	
	}
	
	//This method ensures a one-to-one relationship between user stories and ideas when the user story originates from the idea.
	public static void IdeaUserStoryOneToOne (idea[] ideas, idea[] ideasOld)
	{
		List<id> userStoryIdList = new List<id>();
		for (integer x = 0; x < ideas.size(); x++)
		{
			if(Trigger.IsBefore)if(Trigger.IsUpdate)
			{
				if(ideas[x].user_story__c != ideasOld[x].User_Story__c)if(ideas[x].user_story__c != Null)
				{
					userStoryIdList.add(ideas[x].user_story__c);
				}
			}
			else
			{
				if(ideas[x].user_story__c != Null)
				{
					userStoryIdList.add(ideas[x].user_story__c);
				}
			}
		}
		idea[] dupIdeas=[select title from idea where user_story__c in :userStoryIdList];
		If (dupIdeas.size()>0)
		{
			for(idea i: ideas)
			{
				i.adderror('There is already an Idea associated with that User Story. Please select another.');
			}
		}
	
	} 

	//This method ensures a one-to-one relationship between user stories and ideas when the idea originates from the user story
	//called by a before update trigger
	public static void UserStoryIdeaOneToOne (User_Story__c[] userStories)
	{
		List<id> userStoryIdList = new List<id>();
		for (integer x = 0; x < userStories.size(); x++)
		{
			If(UserStories[x].send_to_ideas__c==true)If(UserStories[x].reviewed__c==true)If(UserStories[x].send_to_solutions__c==false)
			{
				userStoryIdList.add(userStories[x].id);
			}
		}
		for(idea dupIdea:[select id,title,user_story__c from idea where user_story__c in :userStoryIdList])
		{
			for(User_Story__c u: UserStories)
			{
				if (u.id == dupIdea.User_Story__c)
				{
					u.adderror('An Idea, "' + dupIdea.title + '", is already associated with this User Story. The issue must be resolved before this User Story can spawn a new Idea.');
				}
			}
		}
	
	} 
}